package fun.ipconfig.shopping.configure.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import fun.ipconfig.shopping.entity.UserEntity;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author gtl
 */
@Component
public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    private static final String HTTP_POST = "POST";
    private static final String LONGIN_URL = "/login";
    public AuthenticationFilter(AuthenticationManager authenticationManager, SecurityContextRepository securityContextRepository) {
        super(new AntPathRequestMatcher(LONGIN_URL, HTTP_POST));
        this.setAuthenticationManager(authenticationManager);
        setSecurityContextRepository(securityContextRepository);
        this.setAuthenticationSuccessHandler(
                (request, response, authentication) ->
                request.getRequestDispatcher("/success").forward(request, response)
        );
        this.setAuthenticationFailureHandler(
                (request, response, authentication) -> 
                        request.getRequestDispatcher("/fail/error").forward(request, response)
        );
    }
    
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, ServletException, IOException {
        if (!request.getMethod().equals(HTTP_POST)) {
            request.getRequestDispatcher("/fail/认证方法仅支持POST").forward(request, response);
            return null;
        }
        UserEntity user = getUserEntity(request);
        if(user == null){
            logger.info("参数错误");
            request.getRequestDispatcher("/fail/参数错误!").forward(request, response);
            return null;
        }
        UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken
                .unauthenticated(user.getUser(), user.getPasswd());
        setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }

    private UserEntity getUserEntity(HttpServletRequest request) {
        try {
            ObjectMapper om = new ObjectMapper();
            return om.readValue(request.getInputStream(), UserEntity.class);
        } catch (IOException e) {
            logger.debug(e.getMessage());
            return null;
        }
    }
}

